package com.itheima.tanhua.server.controller;

import cn.hutool.core.collection.CollUtil;
import com.itheima.commons.holder.TokenHolder;
import com.itheima.tanhua.model.dto.LocationDto;
import com.itheima.tanhua.model.dto.TestDto;
import com.itheima.tanhua.server.thread.MyCallable;
import io.lettuce.core.api.reactive.RedisGeoReactiveCommands;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author itheima
 * @since 2022-03-09
 */
@RestController
@RequestMapping("baidu")
public class BaiduController {

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/location")
    public ResponseEntity submitLocation(@RequestBody LocationDto dto) throws ExecutionException, InterruptedException {

        String userId = StringUtils.isNotBlank(dto.getUserId()) ? dto.getUserId() : TokenHolder.getUserId();

        Double longitude = dto.getLongitude();
        Double latitude = dto.getLatitude();

        String addrStr = dto.getAddrStr();

        // 将经纬度信息，和当前位置名称写入Redis
        // key为当前用户的id
        Point point = new Point(longitude, latitude);

        // geo参数代表数据存储的分组名
        // add(参数一：坐标，值）
        redisTemplate.boundGeoOps("geo").add(point, userId);

        TimeUnit unit;
        BlockingQueue workQueue;
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
        MyCallable myCallable = new MyCallable();

        Future<String> submit = threadPoolExecutor.submit(myCallable);

        String s = submit.get();

        System.out.println(s);

        return ResponseEntity.ok(null);
    }

    @GetMapping("/location")
    public ResponseEntity getLocation(@RequestBody LocationDto dto) {

        Distance distance = new Distance(dto.getRadius(), Metrics.KILOMETERS);
        Circle circle = new Circle(new Point(dto.getLongitude(), dto.getLatitude()), distance);

        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        args.sortAscending()
                .includeCoordinates()
                .includeDistance()
                .limit(10);

        GeoResults<RedisGeoCommands.GeoLocation<String>> geo = redisTemplate.boundGeoOps("geo").radius(circle, args);

        if (CollUtil.isEmpty(geo)) {
            return ResponseEntity.ok(null);
        }

        List<Map<String, Object>> list = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> result : geo) {
            RedisGeoCommands.GeoLocation<String> location = result.getContent();

            String name = location.getName();
            Point point = location.getPoint();

            Map<String, Object> map = new HashMap<>();
            map.put("name", name);
            map.put("x", point.getX());
            map.put("y", point.getY());
            list.add(map);
        }

        return ResponseEntity.ok(list);
    }

    // 1. query模式：http://localhost/baidu/list/query?name=1&age=14
    @PostMapping("list/query")
    public String testParameterQuery(@RequestParam("name") String name, @RequestParam("age") Integer age) {
        return name + ":" + age;
    }

    // 2. body模式：http://localhost/baidu/list/body
    // {
    //      "name":"2",
    //      "age": 14
    // }
    @PostMapping("list/body")
    public String testParameterBody(@RequestBody TestDto dto) {
        return dto.getName() + ":" + dto.getAge();
    }


    // 3. rest模式：http://localhost/baidu/list/rest/3/15
    @PostMapping("list/rest/{name}/{age}")
    public String testParameterRest(@PathVariable String name, @PathVariable Integer age) {
        return name + ":" + age;
    }

    // 4. formdata模式：http://localhost/baidu/list/formdata
    // 这种模式一般来说是上传图片用的
    // 或者一个请求里面，包含的图片上传 + 其他参数
    @PostMapping("list/formdata")
    public String testParameterFormData(MultipartFile file, TestDto dto) {
        return dto.getName() + ":" + dto.getAge() + ":" + file.getContentType();
    }

}
